package cn.iocoder.yudao.module.infra.controller.admin.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.controller.app.file.vo.BucketPolicyConfigDto;
import cn.iocoder.yudao.module.infra.controller.app.file.vo.MinioUploadDto;
import io.minio.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;

@Tag(name = "管理后台 - MinIO对象存储管理")
@RestController
@RequestMapping("/system/minio")
@Slf4j
public class MinioController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioController.class);
    @Value("${minio.endpoint}")
    private String ENDPOINT;
    @Value("${minio.bucketName}")
    private String BUCKET_NAME;
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;

//    @Operation(summary = "上传图片")
//    @RequestMapping(value = "/upload", method = RequestMethod.POST)
//    public CommonResult upload(@RequestPart("file") MultipartFile file) {
//        try {
//            //创建一个MinIO的Java客户端
//            MinioClient minioClient = MinioClient.builder()
//                    .endpoint(ENDPOINT)
//                    .credentials(ACCESS_KEY, SECRET_KEY)
//                    .build();
//            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
//            if (isExist) {
//                LOGGER.info("存储桶已经存在！");
//            } else {
//                //创建存储桶并设置只读权限
//                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());
//                BucketPolicyConfigDto bucketPolicyConfigDto = createBucketPolicyConfigDto(BUCKET_NAME);
//                SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder()
//                        .bucket(BUCKET_NAME)
//                        .config(JSONUtil.toJsonStr(bucketPolicyConfigDto))
//                        .build();
//                minioClient.setBucketPolicy(setBucketPolicyArgs);
//            }
//            String filename = file.getOriginalFilename();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//            // 设置存储对象名称
//            String objectName = sdf.format(new Date()) + "/" + filename;
//            // 使用putObject上传一个文件到存储桶中
//            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
//                    .bucket(BUCKET_NAME)
//                    .object(objectName)
//                    .contentType(file.getContentType())
//                    .stream(file.getInputStream(), file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build();
//            minioClient.putObject(putObjectArgs);
//            LOGGER.info("文件上传成功!");
//            MinioUploadDto minioUploadDto = new MinioUploadDto();
//            minioUploadDto.setName(filename);
//            minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
//            return CommonResult.success(minioUploadDto);
//        } catch (Exception e) {
//            e.printStackTrace();
//            LOGGER.info("上传发生错误: {}！", e.getMessage());
//        }
//        return CommonResult.error(INTERNAL_SERVER_ERROR);
//    }

    @Operation(summary = "上传图片")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public CommonResult upload(@RequestPart("file") MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) { // 确保输入流在使用完后关闭
            // 创建一个MinIO的Java客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY, SECRET_KEY)
                    .build();
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
            if (isExist) {
                LOGGER.info("存储桶已经存在！");
            } else {
                // 创建存储桶并设置只读权限
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());
                BucketPolicyConfigDto bucketPolicyConfigDto = createBucketPolicyConfigDto(BUCKET_NAME);
                SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder()
                        .bucket(BUCKET_NAME)
                        .config(JSONUtil.toJsonStr(bucketPolicyConfigDto))
                        .build();
                minioClient.setBucketPolicy(setBucketPolicyArgs);
            }
            String charRand = UUID.randomUUID().toString().replace("-", "");
            String filename = charRand.substring(0, 7) + file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称
            String objectName = sdf.format(new Date()) + "/" + filename;

            // 打印调试信息
//            System.out.println("Uploading to bucket: " + BUCKET_NAME);
            System.out.println("Object name: " + objectName);
//            System.out.println("Content type: " + file.getContentType());
//            System.out.println("File size: " + file.getSize());

            // 使用putObject上传一个文件到存储桶中
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(BUCKET_NAME)
                    .object(objectName)
                    .contentType(file.getContentType())
                    .stream(inputStream, file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build();
            minioClient.putObject(putObjectArgs);
            LOGGER.info("文件上传成功!");
            MinioUploadDto minioUploadDto = new MinioUploadDto();
            minioUploadDto.setName(objectName);
            minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
            return CommonResult.success(minioUploadDto);
        } catch (Exception e) {
            LOGGER.error("上传发生错误: {}", e.getMessage(), e);
        }
        return CommonResult.error(INTERNAL_SERVER_ERROR);
    }


    private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName) {
        BucketPolicyConfigDto.Statement statement = BucketPolicyConfigDto.Statement.builder()
                .Effect("Allow")
                .Principal("*")
                .Action("s3:GetObject")
                .Resource("arn:aws:s3:::" + bucketName + "/*.**").build();
        return BucketPolicyConfigDto.builder()
                .Version("2012-10-17")
                .Statement(CollUtil.toList(statement))
                .build();
    }

    @Operation(summary = "文件删除")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public CommonResult delete(@RequestParam("objectName") String objectName) {
        try {
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY, SECRET_KEY)
                    .build();
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build());
            CommonResult result = new CommonResult<>();
            result.setMsg("删除成功");
            result.setCode(0);
            result.isSuccess();
            result.setData("");
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.error(INTERNAL_SERVER_ERROR);
    }
}